package com.dhms.vostok1.adapter

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.databinding.BindingAdapter
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil.load
import com.dhms.basebusiness.R
import com.dhms.uikit.TitleCardView
import com.dhms.vostok1.data.BLEDeviceType
import com.dhms.vostok1.data.LocalUserInfoData
import com.dhms.vostok1.data.abnormals.FaultState
import com.dhms.vostok1.data.message_center.*
import com.dhms.vostok1.data.spot_patrol.TaskStatus
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_RUNNING
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_STOP
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_UNKNOWN


private const val TAG = "BindingAdapters"

@BindingAdapter("anyText")
fun bindText(textView: TextView, text: Any?) {
    textView.text = text?.toString() ?: textView.context.getString(R.string.null_string)
}



@BindingAdapter("image")
fun bindImage(imgView: ImageView, url: String?) {
    url.let {
        if (url == null) {
            imgView.setImageResource(R.drawable.ic_placeholder)
            return
        }
        val imgUri = url.toUri().buildUpon().scheme("https").build()
        imgView.load(imgUri) {
            placeholder(R.drawable.ic_placeholder)
            error(R.drawable.ic_placeholder)
        }
    }
}

@BindingAdapter("base64Image")
fun bindBase64Image(imgView: ImageView, base64String: String?) {
    base64String?.let {
        try {
            val toBeDecodedString = base64String.split("base64,")[1]
            val decodedString = Base64.decode(toBeDecodedString, Base64.DEFAULT)
            val decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
            imgView.setImageBitmap(decodedByte)
        } catch (e: Exception) {
            Log.e(TAG, "Invalid base64 string: $base64String.")
        }
    }
}

@BindingAdapter("bitmapImage")
fun bindBitmapImage(imgView: ImageView, bitmap: Bitmap?) {
    bitmap?.let {
        imgView.setImageBitmap(it)
    }
}

@BindingAdapter("tintColor")
fun bindTintColor(imageView: ImageView, color: Int) {
    imageView.setColorFilter(color)
}


@BindingAdapter("avatar")
fun bindUserAvatar(imgView: ImageView, userInfoData: LocalUserInfoData?) {
    val userAvatarUrl = userInfoData?.avatar
    userAvatarUrl?.let {
        val imgUri = userAvatarUrl.toUri().buildUpon().scheme("https").build()
        imgView.load(imgUri) {
            placeholder(R.drawable.ic_avatar_placeholder)
            error(R.drawable.ic_avatar_placeholder)
        }
    }
}

@SuppressLint("ResourceAsColor")
@BindingAdapter("taskGroupStatus")
fun bindTaskGroupStatus(textView: TextView, status: TaskStatus?) {
    textView.apply {
        when (status) {
            TaskStatus.DOING -> {
                text = context.getString(R.string.task_status_underway)
                setTextColor(ContextCompat.getColor(context, R.color.task_status_underway))
            }
            TaskStatus.UN_START -> {
                text = context.getString(R.string.task_status_not_start)
                setTextColor(ContextCompat.getColor(context, R.color.task_status_not_start))
            }
            TaskStatus.DONE -> {
                text = context.getString(R.string.task_status_done)
                setTextColor(ContextCompat.getColor(context, R.color.task_status_done))
            }
            TaskStatus.TIMEOUT -> {
                text = context.getString(R.string.task_status_overtime)
                setTextColor(ContextCompat.getColor(context, R.color.task_status_overtime))
            }
            TaskStatus.TIMEOUT_DONE -> {
                text = context.getString(R.string.task_status_overtime_done)
                setTextColor(ContextCompat.getColor(context, R.color.task_status_overtime_done))
            }
            else -> {
                text = context.getString(R.string.null_string)
                setTextColor(ContextCompat.getColor(context, R.color.status_unknown))
            }
        }
    }
}

@BindingAdapter("simpleInfoItemColor")
fun bindSimpleInfoItemColor(textView: TextView, color: Int) {
    if (color == 0) {
        return
    }
    textView.setTextColor(color)
}

@BindingAdapter("tgCardState")
fun bindTaskGroupCardState(cardView: TitleCardView, status: TaskStatus?) {
    cardView.binding.apply {
        val context = cardView.context
        when (status) {
            TaskStatus.DOING -> {
                state = context.getString(R.string.task_status_underway)
                stateColor = ContextCompat.getColor(context, R.color.task_status_underway)
            }
            TaskStatus.UN_START -> {
                state = context.getString(R.string.task_status_not_start)
                stateColor = ContextCompat.getColor(context, R.color.task_status_not_start)
            }
            TaskStatus.DONE -> {
                state = context.getString(R.string.task_status_done)
                stateColor = ContextCompat.getColor(context, R.color.task_status_done)
            }
            TaskStatus.TIMEOUT -> {
                state = context.getString(R.string.task_status_overtime)
                stateColor = ContextCompat.getColor(context, R.color.task_status_overtime)
            }
            TaskStatus.TIMEOUT_DONE -> {
                state = context.getString(R.string.task_status_overtime_done)
                stateColor = ContextCompat.getColor(context, R.color.task_status_overtime_done)
            }
            else -> {
                state = context.getString(R.string.null_string)
                stateColor = ContextCompat.getColor(context, R.color.status_unknown)
            }
        }
    }
}

@BindingAdapter("spItemState")
fun bindSpItemState(textView: TextView, isAbnormal: Boolean) {
    textView.apply {
        if (isAbnormal) {
            text = context.getString(R.string.task_status_abnormal)
            setTextColor(ContextCompat.getColor(context, R.color.status_abnormal))
        } else {
            text = context.getString(R.string.task_status_normal)
            setTextColor(ContextCompat.getColor(context, R.color.status_normal))
        }
    }
}

@BindingAdapter("textColor")
fun bindTextColor(textView: TextView, color: Int?) {
    if (color == 0 || color == null) {
        return
    }
    textView.apply {
        setTextColor(ContextCompat.getColor(context, color))
    }
}

@BindingAdapter("deviceStatusTag")
fun bindDeviceStatusTag(imageView: ImageView, status: Int) {
    imageView.apply {
        when (status) {
            DEVICE_STATE_RUNNING -> {
                setColorFilter(
                    ContextCompat.getColor(
                        context,
                        R.color.status_normal
                    )
                )
            }
            DEVICE_STATE_STOP -> {
                setColorFilter(
                    ContextCompat.getColor(
                        context,
                        R.color.status_abnormal
                    )
                )
            }
            DEVICE_STATE_UNKNOWN -> {
                setColorFilter(
                    ContextCompat.getColor(
                        context,
                        R.color.status_unknown
                    )
                )
            }
        }
    }
}

@BindingAdapter("deviceStatusText")
fun bindDeviceStatusText(textView: TextView, status: Int) {
    textView.apply {
        when (status) {
            DEVICE_STATE_RUNNING -> {
                text = context.getString(R.string.device_status_running)
                setTextColor(ContextCompat.getColor(context, R.color.status_normal))
            }
            DEVICE_STATE_STOP -> {
                text = context.getString(R.string.device_status_stop)
                setTextColor(ContextCompat.getColor(context, R.color.status_abnormal))
            }
            DEVICE_STATE_UNKNOWN -> {
                text = context.getString(R.string.device_status_offline)
                setTextColor(ContextCompat.getColor(context, R.color.status_unknown))
            }
        }
    }
}

@BindingAdapter("isRefreshing")
fun bindDeviceLoadingState(swipeRefreshLayout: SwipeRefreshLayout, state: Boolean) {
    swipeRefreshLayout.isRefreshing = state
}

@BindingAdapter("textCard")
fun bindTextCard(cardView: TitleCardView, s: String) {
    cardView.binding.cardState.apply {
        cardView.binding.state = s
        cardView.binding.stateColor = ContextCompat.getColor(context, R.color.error)
    }
}



@BindingAdapter("faultStateImage")
fun bindFaultStateImage(imageView: ImageView, faultState: FaultState?) {
    imageView.apply {
        when (faultState) {
            FaultState.OBSERVING -> imageView.setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.img_fault_observing
                )
            )
            FaultState.HANDLED -> imageView.setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.img_fault_handled
                )
            )
            FaultState.OCCURRED -> imageView.setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.img_fault_occured
                )
            )
            FaultState.CANCELLED -> imageView.setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.img_fault_cancelled
                )
            )
            FaultState.ACCEPTED -> imageView.setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.img_fault_accepted
                )
            )
            else -> {}
        }
    }
}


@BindingAdapter("bleDeviceImage")
fun bindBleDeviceImage(imageView: ImageView, deviceType: BLEDeviceType) {
    imageView.apply {
        when (deviceType) {
            BLEDeviceType.DHMS_SPC_DEVICE,
            BLEDeviceType.ZHENG_CHAO_SPC_DEVICE -> {
                setImageDrawable(
                    ContextCompat.getDrawable(
                        context,
                        R.drawable.img_check_instrument_render_graph
                    )
                )
            }
            else -> {
                setImageDrawable(
                    ContextCompat.getDrawable(
                        context,
                        R.drawable.ic_ble_device_plackholder
                    )
                )
            }
        }
    }
}

@BindingAdapter("powerLevel")
fun bindPowerLevel(imageView: ImageView, power: Float?) {
    if (power == null) {
        imageView.visibility = View.INVISIBLE
        return
    }

    imageView.visibility = View.VISIBLE
    when ((power * 100).toInt()) {
        in 0 until 20 -> { // [0, 20)
            imageView.setImageResource(R.drawable.ic_battery_level_1)
        }
        in 20 until 40 -> {
            imageView.setImageResource(R.drawable.ic_battery_level_2)
        }
        in 40 until 60 -> {
            imageView.setImageResource(R.drawable.ic_battery_level_3)
        }
        in 60 until 80 -> {
            imageView.setImageResource(R.drawable.ic_battery_level_4)
        }
        in 80..100 -> { // [80, 100]
            imageView.setImageResource(R.drawable.ic_battery_level_5)
        }
        else -> {
            imageView.visibility = View.GONE
        }
    }
}

@BindingAdapter("messageCenterItemImage")
fun bindMessageCenterItemImage(imageView: ImageView, item: MessageCenterData) {
    imageView.apply {

        val resId = when (MessageCenterType.fromString(item.messageGroup)) {
            MessageCenterType.MAINTENANCE -> R.drawable.ic_maintenance
            MessageCenterType.LUBRICATION -> R.drawable.ic_lubrication
            MessageCenterType.SPOT_PATROL -> R.drawable.ic_spot_patrol
            MessageCenterType.PERIL -> R.drawable.ic_peril
            MessageCenterType.FAULT -> R.drawable.ic_fault
            MessageCenterType.REPAIR -> R.drawable.ic_repair
            MessageCenterType.WAREHOUSE_OUT -> R.drawable.ic_issue
            else -> R.drawable.ic_approval
        }

        imageView.setImageDrawable(
            ContextCompat.getDrawable(
                context,
                resId
            )
        )
    }
}

@BindingAdapter("messageCenterItemTitle")
fun bindMessageCenterItemTitle(textView: TextView, item: MessageCenterData) {
    textView.apply {

        val resId = when (MessageCenterType.fromString(item.messageGroup)) {
            MessageCenterType.MAINTENANCE -> R.string.message_center_maintenance
            MessageCenterType.LUBRICATION -> R.string.message_center_lubrication
            MessageCenterType.SPOT_PATROL -> R.string.message_center_spot_patrol
            MessageCenterType.PERIL -> R.string.message_center_peril
            MessageCenterType.REPAIR -> R.string.message_center_repair
            MessageCenterType.WAREHOUSE_OUT -> R.string.message_center_issue
            MessageCenterType.FAULT -> R.string.message_center_fault
            else -> R.string.message_center_approval
        }

        text = context.getString(resId)
    }
}

@BindingAdapter("messageContentPaddingLeft")
fun bindMessageContentPaddingLeft(textView: TextView, item: MessageItemData) {
    textView.apply {
        val left =
            if (item.isRead == 1) resources.getDimension(R.dimen.no_interval) else resources.getDimension(
                R.dimen.text_medium_interval
            )
        setPadding(left.toInt(), 0, 0, 0)
    }
}

@BindingAdapter("messageItemApprovalState")
fun bindMessageItemApprovalState(imageView: ImageView, item: MessageItemData) {
    imageView.apply {
        visibility = View.GONE
        item.messageType?.let { messageType ->
            var resId: Int? = null

            if (messageType.contains(MessageTaskStateType.NOTIFY_FLOW_APPROVED.value)) {
                resId = R.drawable.img_message_pass
            } else if (messageType.contains(MessageTaskStateType.NOTIFY_FLOW_REJECTED.value)) {
                resId = R.drawable.img_message_refuse
            } else if (messageType.contains(MessageTaskStateType.NOTIFY_FLOW_REVOKED.value) ||
                messageType.contains(MessageTaskStateType.NOTIFY_INITIATOR_FLOW_REVOKED.value)
            ) {
                resId = R.drawable.img_message_revoked
            }

            /**
             * 出库消息 特殊处理
             * */
            if (messageType == MessageApprovalType.WAREHOUSE_OUT_ORDER_NOTIFY_FLOW_APPROVED.value) {
                resId = R.drawable.ic_subimit
            } else if (messageType == MessageApprovalType.WAREHOUSE_OUT_ORDER_NOTIFY_FLOW_REVOKED.value) {
                resId = R.drawable.ic_voided
            }

            resId?.let {
                visibility = View.VISIBLE
                setImageDrawable(
                    ContextCompat.getDrawable(
                        context,
                        resId
                    )
                )
            }
        }
    }
}



